<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
    <script src="../js/vue.global.js"></script>
</head>

<body>
    <div id="app">
        <p>count:{{count}}</p>
        <p>
            <button @click="addCount">count++</button>
            <button @click="count++">count++</button>
        </p>
    </div>
</body>
<script>

    // 组合式 API 的核心思想是直接在函数作用域内定义响应式状态变量，并将从多个函数中得到的状态组合起来处理复杂问题
    
    let { createApp,ref } = Vue;
    console.log(Vue);

    // 创建实例 (根实例)
    let app = createApp({
        setup:function(){ // 组合式写法  => 当前写法也要在选项配置中设置
            console.log("setup函数执行了");
            // 组合式写法
            // 1. setup钩子函数 在所有生命周期执行之前执行=> 此时实例还未创建和挂载 => 无法使用this
            // 2. 在setup函数中 可以定义数据 计算属性 方法 watch监听 生命周期钩子函数 => 通过return返回 => 最终还是会被处理为选项式写法
            //    可以理解为组合式写法可以提前定义数据 计算属性 方法 watch监听 生命周期钩子函数  => 被Vue内部处理为选项式

            // 定义数据


            // 错误示范  !!!!!!!!!!!
            // 直接定义变量存储数据 => Vue响应式检测不到数据改变 => 视图就不会更新
            // let count = 10;
            // let addCount = ()=>{
            //     console.log("addCount执行了",count);
            //     count++;
            // }

            // 解决方案:
            // ref()   创建一个对值类型的引用 => 返回一个ref对象,存在value属性(有getter setter), 当value值发生改变会被Vue响应式检测到 
            
            // 注意:
            // 1. 如果setup函数中返回的值是ref对象,会被代理对象接收,进行解包 

           /*  new Proxy({ // 此写法不对,为了方便理解
                count:{
                    get(){
                        return count.value;
                    },
                    set(val){
                        count.value = val;
                    }
                }
            }) */
                

            let count = ref(10); // {value:10}
            console.log("count",count);
            let addCount = ()=>{
                console.log("addCount执行了",count.value);
                count.value ++;
            }


            return {  // 原理:闭包
                // 返回的对象
                // 键名: 代理对象中的属性名
                // 键值: setup函数中定义的变量和方法
                count:count, // ref对象
                addCount:addCount
            }
        },
        // 选项式写法
        data(){
            return {
                x:10,
                y:10,
            }
        },
        mounted() {
            console.log("mounted");

            // 代理对象  => 默认对象ref对象解包
            
            // new Proxy({ // 此写法不对,为了方便理解
            //     count:{
            //         get(){
            //             return count.value;
            //         },
            //         set(val){
            //             count.value = val;
            //         }
            //     }
            // })
            console.log("this",this);
            console.log("this",this.count);
            this.count ++
            console.log("this",this.count);
        },

       
    })

    console.log("根实例",app);


    // 挂载实例
    app.mount("#app");





</script>

</html>